1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422 |
- // Protocol Buffers - Google's data interchange format
- // Copyright 2008 Google Inc. All rights reserved.
- // https://developers.google.com/protocol-buffers/
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following disclaimer
- // in the documentation and/or other materials provided with the
- // distribution.
- // * Neither the name of Google Inc. nor the names of its
- // contributors may be used to endorse or promote products derived from
- // this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (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 <set>
- #include <google/protobuf/stubs/logging.h>
- #include <google/protobuf/stubs/common.h>
- #include <google/protobuf/descriptor.pb.h>
- #include <google/protobuf/descriptor.h>
- #include <google/protobuf/extension_set.h>
- #include <google/protobuf/generated_message_reflection.h>
- #include <google/protobuf/generated_message_util.h>
- #include <google/protobuf/inlined_string_field.h>
- #include <google/protobuf/map_field.h>
- #include <google/protobuf/repeated_field.h>
- #include <google/protobuf/wire_format.h>
- #define GOOGLE_PROTOBUF_HAS_ONEOF
- namespace google {
- namespace protobuf {
- namespace internal {
- namespace {
- bool IsMapFieldInApi(const FieldDescriptor* field) {
- return field->is_map();
- }
- } // anonymous namespace
- 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 ? GetEmptyString() : d->name());
- }
- // ===================================================================
- // Helpers for reporting usage errors (e.g. trying to use GetInt32() on
- // a string field).
- namespace {
- template <class To>
- To* GetPointerAtOffset(Message* message, uint32 offset) {
- return reinterpret_cast<To*>(reinterpret_cast<char*>(message) + offset);
- }
- template <class To>
- const To* GetConstPointerAtOffset(const Message* message, uint32 offset) {
- return reinterpret_cast<const To*>(reinterpret_cast<const char*>(message) +
- offset);
- }
- template <class To>
- const To& GetConstRefAtOffset(const Message& message, uint32 offset) {
- return *GetConstPointerAtOffset<To>(&message, offset);
- }
- 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 ReflectionSchema& schema,
- const DescriptorPool* pool, MessageFactory* factory)
- : descriptor_(descriptor),
- schema_(schema),
- descriptor_pool_((pool == NULL) ? DescriptorPool::generated_pool()
- : pool),
- message_factory_(factory),
- last_non_weak_field_index_(-1) {
- last_non_weak_field_index_ = descriptor_->field_count() - 1;
- }
- GeneratedMessageReflection::~GeneratedMessageReflection() {}
- const UnknownFieldSet& GeneratedMessageReflection::GetUnknownFields(
- const Message& message) const {
- if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 &&
- !GetProto3PreserveUnknownsDefault()) {
- // We have to ensure that any mutations made to the return value of
- // MutableUnknownFields() are not reflected here when Proto3 defaults to
- // discard unknowns.
- return *UnknownFieldSet::default_instance();
- } else {
- return GetInternalMetadataWithArena(message).unknown_fields();
- }
- }
- UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields(
- Message* message) const {
- return MutableInternalMetadataWithArena(message)->mutable_unknown_fields();
- }
- size_t GeneratedMessageReflection::SpaceUsedLong(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.
- size_t total_size = schema_.GetObjectSize();
- total_size += GetUnknownFields(message).SpaceUsedExcludingSelfLong();
- if (schema_.HasExtensionSet()) {
- total_size += GetExtensionSet(message).SpaceUsedExcludingSelfLong();
- }
- for (int i = 0; i <= last_non_weak_field_index_; 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) \
- .SpaceUsedExcludingSelfLong(); \
- 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)
- .SpaceUsedExcludingSelfLong();
- break;
- }
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- if (IsMapFieldInApi(field)) {
- total_size += GetRaw<MapFieldBase>(message, field)
- .SpaceUsedExcludingSelfLong();
- } else {
- // We don't know which subclass of RepeatedPtrFieldBase the type is,
- // so we use RepeatedPtrFieldBase directly.
- total_size +=
- GetRaw<RepeatedPtrFieldBase>(message, field)
- .SpaceUsedExcludingSelfLong<GenericTypeHandler<Message> >();
- }
- break;
- }
- } else {
- if (field->containing_oneof() && !HasOneofField(message, field)) {
- continue;
- }
- 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: {
- if (IsInlined(field)) {
- const string* ptr =
- &GetField<InlinedStringField>(message, field).GetNoArena();
- total_size += StringSpaceUsedExcludingSelfLong(*ptr);
- break;
- }
- // 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<ArenaStringPtr>(field).Get();
- const string* ptr =
- &GetField<ArenaStringPtr>(message, field).Get();
- if (ptr != default_ptr) {
- // string fields are represented by just a pointer, so also
- // include sizeof(string) as well.
- total_size +=
- sizeof(*ptr) + StringSpaceUsedExcludingSelfLong(*ptr);
- }
- break;
- }
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_MESSAGE:
- if (schema_.IsDefaultInstance(message)) {
- // 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->SpaceUsedLong();
- }
- }
- break;
- }
- }
- }
- return total_size;
- }
- void GeneratedMessageReflection::SwapField(
- Message* message1,
- Message* message2,
- const FieldDescriptor* field) const {
- 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:
- switch (field->options().ctype()) {
- default: // TODO(kenton): Support other string reps.
- case FieldOptions::STRING:
- MutableRaw<RepeatedPtrFieldBase>(message1, field)->
- Swap<GenericTypeHandler<string> >(
- MutableRaw<RepeatedPtrFieldBase>(message2, field));
- break;
- }
- break;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- if (IsMapFieldInApi(field)) {
- MutableRaw<MapFieldBase>(message1, field)->
- MutableRepeatedField()->
- Swap<GenericTypeHandler<google::protobuf::Message> >(
- MutableRaw<MapFieldBase>(message2, field)->
- MutableRepeatedField());
- } else {
- MutableRaw<RepeatedPtrFieldBase>(message1, field)->
- Swap<GenericTypeHandler<google::protobuf::Message> >(
- 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 );
- #undef SWAP_VALUES
- case FieldDescriptor::CPPTYPE_MESSAGE:
- if (GetArena(message1) == GetArena(message2)) {
- std::swap(*MutableRaw<Message*>(message1, field),
- *MutableRaw<Message*>(message2, field));
- } else {
- Message** sub_msg1 = MutableRaw<Message*>(message1, field);
- Message** sub_msg2 = MutableRaw<Message*>(message2, field);
- if (*sub_msg1 == NULL && *sub_msg2 == NULL) break;
- if (*sub_msg1 && *sub_msg2) {
- (*sub_msg1)->GetReflection()->Swap(*sub_msg1, *sub_msg2);
- break;
- }
- if (*sub_msg1 == NULL) {
- *sub_msg1 = (*sub_msg2)->New(message1->GetArena());
- (*sub_msg1)->CopyFrom(**sub_msg2);
- ClearField(message2, field);
- } else {
- *sub_msg2 = (*sub_msg1)->New(message2->GetArena());
- (*sub_msg2)->CopyFrom(**sub_msg1);
- ClearField(message1, field);
- }
- }
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- switch (field->options().ctype()) {
- default: // TODO(kenton): Support other string reps.
- case FieldOptions::STRING:
- {
- Arena* arena1 = GetArena(message1);
- Arena* arena2 = GetArena(message2);
- if (IsInlined(field)) {
- InlinedStringField* string1 =
- MutableRaw<InlinedStringField>(message1, field);
- InlinedStringField* string2 =
- MutableRaw<InlinedStringField>(message2, field);
- string1->Swap(string2);
- break;
- }
- ArenaStringPtr* string1 =
- MutableRaw<ArenaStringPtr>(message1, field);
- ArenaStringPtr* string2 =
- MutableRaw<ArenaStringPtr>(message2, field);
- const string* default_ptr =
- &DefaultRaw<ArenaStringPtr>(field).Get();
- if (arena1 == arena2) {
- string1->Swap(string2, default_ptr, arena1);
- } else {
- const string temp = string1->Get();
- string1->Set(default_ptr, string2->Get(), arena1);
- string2->Set(default_ptr, temp, arena2);
- }
- }
- break;
- }
- break;
- default:
- GOOGLE_LOG(FATAL) << "Unimplemented type: " << field->cpp_type();
- }
- }
- }
- void GeneratedMessageReflection::SwapOneofField(
- Message* message1,
- Message* message2,
- const OneofDescriptor* oneof_descriptor) const {
- uint32 oneof_case1 = GetOneofCase(*message1, oneof_descriptor);
- uint32 oneof_case2 = GetOneofCase(*message2, oneof_descriptor);
- int32 temp_int32;
- int64 temp_int64;
- uint32 temp_uint32;
- uint64 temp_uint64;
- float temp_float;
- double temp_double;
- bool temp_bool;
- int temp_int;
- Message* temp_message = NULL;
- string temp_string;
- // Stores message1's oneof field to a temp variable.
- const FieldDescriptor* field1 = NULL;
- if (oneof_case1 > 0) {
- field1 = descriptor_->FindFieldByNumber(oneof_case1);
- //oneof_descriptor->field(oneof_case1);
- switch (field1->cpp_type()) {
- #define GET_TEMP_VALUE(CPPTYPE, TYPE) \
- case FieldDescriptor::CPPTYPE_##CPPTYPE: \
- temp_##TYPE = GetField<TYPE>(*message1, field1); \
- break;
- GET_TEMP_VALUE(INT32 , int32 );
- GET_TEMP_VALUE(INT64 , int64 );
- GET_TEMP_VALUE(UINT32, uint32);
- GET_TEMP_VALUE(UINT64, uint64);
- GET_TEMP_VALUE(FLOAT , float );
- GET_TEMP_VALUE(DOUBLE, double);
- GET_TEMP_VALUE(BOOL , bool );
- GET_TEMP_VALUE(ENUM , int );
- #undef GET_TEMP_VALUE
- case FieldDescriptor::CPPTYPE_MESSAGE:
- temp_message = ReleaseMessage(message1, field1);
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- temp_string = GetString(*message1, field1);
- break;
- default:
- GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
- }
- }
- // Sets message1's oneof field from the message2's oneof field.
- if (oneof_case2 > 0) {
- const FieldDescriptor* field2 =
- descriptor_->FindFieldByNumber(oneof_case2);
- switch (field2->cpp_type()) {
- #define SET_ONEOF_VALUE1(CPPTYPE, TYPE) \
- case FieldDescriptor::CPPTYPE_##CPPTYPE: \
- SetField<TYPE>(message1, field2, GetField<TYPE>(*message2, field2)); \
- break;
- SET_ONEOF_VALUE1(INT32 , int32 );
- SET_ONEOF_VALUE1(INT64 , int64 );
- SET_ONEOF_VALUE1(UINT32, uint32);
- SET_ONEOF_VALUE1(UINT64, uint64);
- SET_ONEOF_VALUE1(FLOAT , float );
- SET_ONEOF_VALUE1(DOUBLE, double);
- SET_ONEOF_VALUE1(BOOL , bool );
- SET_ONEOF_VALUE1(ENUM , int );
- #undef SET_ONEOF_VALUE1
- case FieldDescriptor::CPPTYPE_MESSAGE:
- SetAllocatedMessage(message1,
- ReleaseMessage(message2, field2),
- field2);
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- SetString(message1, field2, GetString(*message2, field2));
- break;
- default:
- GOOGLE_LOG(FATAL) << "Unimplemented type: " << field2->cpp_type();
- }
- } else {
- ClearOneof(message1, oneof_descriptor);
- }
- // Sets message2's oneof field from the temp variable.
- if (oneof_case1 > 0) {
- switch (field1->cpp_type()) {
- #define SET_ONEOF_VALUE2(CPPTYPE, TYPE) \
- case FieldDescriptor::CPPTYPE_##CPPTYPE: \
- SetField<TYPE>(message2, field1, temp_##TYPE); \
- break;
- SET_ONEOF_VALUE2(INT32 , int32 );
- SET_ONEOF_VALUE2(INT64 , int64 );
- SET_ONEOF_VALUE2(UINT32, uint32);
- SET_ONEOF_VALUE2(UINT64, uint64);
- SET_ONEOF_VALUE2(FLOAT , float );
- SET_ONEOF_VALUE2(DOUBLE, double);
- SET_ONEOF_VALUE2(BOOL , bool );
- SET_ONEOF_VALUE2(ENUM , int );
- #undef SET_ONEOF_VALUE2
- case FieldDescriptor::CPPTYPE_MESSAGE:
- SetAllocatedMessage(message2, temp_message, field1);
- break;
- case FieldDescriptor::CPPTYPE_STRING:
- SetString(message2, field1, temp_string);
- break;
- default:
- GOOGLE_LOG(FATAL) << "Unimplemented type: " << field1->cpp_type();
- }
- } else {
- ClearOneof(message2, oneof_descriptor);
- }
- }
- 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 \""
- << message2->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.";
- // Check that both messages are in the same arena (or both on the heap). We
- // need to copy all data if not, due to ownership semantics.
- if (GetArena(message1) != GetArena(message2)) {
- // Slow copy path.
- // Use our arena as temp space, if available.
- Message* temp = message1->New(GetArena(message1));
- temp->MergeFrom(*message2);
- message2->CopyFrom(*message1);
- Swap(message1, temp);
- if (GetArena(message1) == NULL) {
- delete temp;
- }
- return;
- }
- if (schema_.HasHasbits()) {
- uint32* has_bits1 = MutableHasBits(message1);
- uint32* has_bits2 = MutableHasBits(message2);
- int fields_with_has_bits = 0;
- for (int i = 0; i < descriptor_->field_count(); i++) {
- const FieldDescriptor* field = descriptor_->field(i);
- if (field->is_repeated() || field->containing_oneof()) {
- continue;
- }
- fields_with_has_bits++;
- }
- int has_bits_size = (fields_with_has_bits + 31) / 32;
- for (int i = 0; i < has_bits_size; i++) {
- std::swap(has_bits1[i], has_bits2[i]);
- }
- }
- for (int i = 0; i <= last_non_weak_field_index_; i++) {
- const FieldDescriptor* field = descriptor_->field(i);
- if (field->containing_oneof()) continue;
- SwapField(message1, message2, field);
- }
- const int oneof_decl_count = descriptor_->oneof_decl_count();
- for (int i = 0; i < oneof_decl_count; i++) {
- SwapOneofField(message1, message2, descriptor_->oneof_decl(i));
- }
- if (schema_.HasExtensionSet()) {
- MutableExtensionSet(message1)->Swap(MutableExtensionSet(message2));
- }
- MutableUnknownFields(message1)->Swap(MutableUnknownFields(message2));
- }
- void GeneratedMessageReflection::SwapFields(
- Message* message1,
- Message* message2,
- const std::vector<const FieldDescriptor*>& fields) const {
- if (message1 == message2) return;
- // TODO(kenton): Other Reflection methods should probably check this too.
- GOOGLE_CHECK_EQ(message1->GetReflection(), this)
- << "First argument to SwapFields() (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 SwapFields() (of type \""
- << message2->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.";
- std::set<int> swapped_oneof;
- const int fields_size = static_cast<int>(fields.size());
- for (int i = 0; i < fields_size; i++) {
- const FieldDescriptor* field = fields[i];
- if (field->is_extension()) {
- MutableExtensionSet(message1)->SwapExtension(
- MutableExtensionSet(message2),
- field->number());
- } else {
- if (field->containing_oneof()) {
- int oneof_index = field->containing_oneof()->index();
- // Only swap the oneof field once.
- if (swapped_oneof.find(oneof_index) != swapped_oneof.end()) {
- continue;
- }
- swapped_oneof.insert(oneof_index);
- SwapOneofField(message1, message2, field->containing_oneof());
- } else {
- // Swap has bit for non-repeated fields. We have already checked for
- // oneof already.
- if (!field->is_repeated()) {
- SwapBit(message1, message2, field);
- }
- // Swap field.
- SwapField(message1, message2, field);
- }
- }
- }
- }
- // -------------------------------------------------------------------
- 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 {
- if (field->containing_oneof()) {
- return HasOneofField(message, field);
- } 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:
- if (IsMapFieldInApi(field)) {
- const internal::MapFieldBase& map =
- GetRaw<MapFieldBase>(message, field);
- if (map.IsRepeatedFieldValid()) {
- return map.GetRepeatedField().size();
- } else {
- // No need to materialize the repeated field if it is out of sync:
- // its size will be the same as the map's size.
- return map.size();
- }
- } else {
- 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 (field->containing_oneof()) {
- ClearOneofField(message, field);
- return;
- }
- 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: {
- if (IsInlined(field)) {
- const string* default_ptr =
- &DefaultRaw<InlinedStringField>(field).GetNoArena();
- MutableRaw<InlinedStringField>(message, field)->SetNoArena(
- default_ptr, *default_ptr);
- break;
- }
- const string* default_ptr =
- &DefaultRaw<ArenaStringPtr>(field).Get();
- MutableRaw<ArenaStringPtr>(message, field)->SetAllocated(
- default_ptr, NULL, GetArena(message));
- break;
- }
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_MESSAGE:
- if (!schema_.HasHasbits()) {
- // Proto3 does not have has-bits and we need to set a message field
- // to NULL in order to indicate its un-presence.
- if (GetArena(message) == NULL) {
- delete *MutableRaw<Message*>(message, field);
- }
- *MutableRaw<Message*>(message, field) = NULL;
- } else {
- (*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: {
- if (IsMapFieldInApi(field)) {
- MutableRaw<MapFieldBase>(message, field)
- ->MutableRepeatedField()
- ->Clear<GenericTypeHandler<Message> >();
- } else {
- // 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:
- if (IsMapFieldInApi(field)) {
- MutableRaw<MapFieldBase>(message, field)
- ->MutableRepeatedField()
- ->RemoveLast<GenericTypeHandler<Message> >();
- } else {
- MutableRaw<RepeatedPtrFieldBase>(message, field)
- ->RemoveLast<GenericTypeHandler<Message> >();
- }
- break;
- }
- }
- }
- Message* GeneratedMessageReflection::ReleaseLast(
- Message* message,
- const FieldDescriptor* field) const {
- USAGE_CHECK_ALL(ReleaseLast, REPEATED, MESSAGE);
- if (field->is_extension()) {
- return static_cast<Message*>(
- MutableExtensionSet(message)->ReleaseLast(field->number()));
- } else {
- if (IsMapFieldInApi(field)) {
- return MutableRaw<MapFieldBase>(message, field)
- ->MutableRepeatedField()
- ->ReleaseLast<GenericTypeHandler<Message> >();
- } else {
- return MutableRaw<RepeatedPtrFieldBase>(message, field)
- ->ReleaseLast<GenericTypeHandler<Message> >();
- }
- }
- }
- 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:
- if (IsMapFieldInApi(field)) {
- MutableRaw<MapFieldBase>(message, field)
- ->MutableRepeatedField()
- ->SwapElements(index1, index2);
- } else {
- 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();
- }
- };
- inline bool IsIndexInHasBitSet(
- const uint32* has_bit_set, uint32 has_bit_index) {
- GOOGLE_DCHECK_NE(has_bit_index, ~0u);
- return ((has_bit_set[has_bit_index / 32] >> (has_bit_index % 32)) &
- static_cast<uint32>(1)) != 0;
- }
- } // namespace
- void GeneratedMessageReflection::ListFields(
- const Message& message,
- std::vector<const FieldDescriptor*>* output) const {
- output->clear();
- // Optimization: The default instance never has any fields set.
- if (schema_.IsDefaultInstance(message)) return;
- // Optimization: Avoid calling GetHasBits() and HasOneofField() many times
- // within the field loop. We allow this violation of ReflectionSchema
- // encapsulation because this function takes a noticable about of CPU
- // fleetwide and properly allowing this optimization through public interfaces
- // seems more trouble than it is worth.
- const uint32* const has_bits =
- schema_.HasHasbits() ? GetHasBits(message) : NULL;
- const uint32* const has_bits_indices = schema_.has_bit_indices_;
- const uint32* const oneof_case_array =
- GetConstPointerAtOffset<uint32>(&message, schema_.oneof_case_offset_);
- output->reserve(descriptor_->field_count());
- for (int i = 0; i <= last_non_weak_field_index_; i++) {
- const FieldDescriptor* field = descriptor_->field(i);
- if (field->is_repeated()) {
- if (FieldSize(message, field) > 0) {
- output->push_back(field);
- }
- } else {
- const OneofDescriptor* containing_oneof = field->containing_oneof();
- if (containing_oneof) {
- // Equivalent to: HasOneofField(message, field)
- if (oneof_case_array[containing_oneof->index()] == field->number()) {
- output->push_back(field);
- }
- } else if (has_bits) {
- // Equivalent to: HasBit(message, field)
- if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) {
- output->push_back(field);
- }
- } else if (HasBit(message, field)) { // Fall back on proto3-style HasBit.
- output->push_back(field);
- }
- }
- }
- if (schema_.HasExtensionSet()) {
- GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_,
- output);
- }
- // ListFields() must sort output by field number.
- std::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: {
- if (IsInlined(field)) {
- return GetField<InlinedStringField>(message, field).GetNoArena();
- }
- return GetField<ArenaStringPtr>(message, field).Get();
- }
- }
- }
- }
- 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: {
- if (IsInlined(field)) {
- return GetField<InlinedStringField>(message, field).GetNoArena();
- }
- return GetField<ArenaStringPtr>(message, field).Get();
- }
- }
- }
- }
- 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: {
- if (IsInlined(field)) {
- MutableField<InlinedStringField>(message, field)->SetNoArena(
- NULL, value);
- break;
- }
- const string* default_ptr = &DefaultRaw<ArenaStringPtr>(field).Get();
- if (field->containing_oneof() && !HasOneofField(*message, field)) {
- ClearOneof(message, field->containing_oneof());
- MutableField<ArenaStringPtr>(message, field)->UnsafeSetDefault(
- default_ptr);
- }
- MutableField<ArenaStringPtr>(message, field)->Set(default_ptr,
- value, GetArena(message));
- 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);
- }
- }
- }
- 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);
- }
- }
- }
- 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;
- }
- }
- }
- // -------------------------------------------------------------------
- inline bool CreateUnknownEnumValues(const FileDescriptor* file) {
- return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
- }
- const EnumValueDescriptor* GeneratedMessageReflection::GetEnum(
- const Message& message, const FieldDescriptor* field) const {
- // Usage checked by GetEnumValue.
- int value = GetEnumValue(message, field);
- return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
- }
- int GeneratedMessageReflection::GetEnumValue(
- const Message& message, const FieldDescriptor* field) const {
- USAGE_CHECK_ALL(GetEnumValue, SINGULAR, ENUM);
- int32 value;
- if (field->is_extension()) {
- value = GetExtensionSet(message).GetEnum(
- field->number(), field->default_value_enum()->number());
- } else {
- value = GetField<int>(message, field);
- }
- return value;
- }
- void GeneratedMessageReflection::SetEnum(
- Message* message, const FieldDescriptor* field,
- const EnumValueDescriptor* value) const {
- // Usage checked by SetEnumValue.
- USAGE_CHECK_ENUM_VALUE(SetEnum);
- SetEnumValueInternal(message, field, value->number());
- }
- void GeneratedMessageReflection::SetEnumValue(
- Message* message, const FieldDescriptor* field,
- int value) const {
- USAGE_CHECK_ALL(SetEnumValue, SINGULAR, ENUM);
- if (!CreateUnknownEnumValues(descriptor_->file())) {
- // Check that the value is valid if we don't support direct storage of
- // unknown enum values.
- const EnumValueDescriptor* value_desc =
- field->enum_type()->FindValueByNumber(value);
- if (value_desc == NULL) {
- GOOGLE_LOG(DFATAL) << "SetEnumValue accepts only valid integer values: value "
- << value << " unexpected for field " << field->full_name();
- // In production builds, DFATAL will not terminate the program, so we have
- // to do something reasonable: just set the default value.
- value = field->default_value_enum()->number();
- }
- }
- SetEnumValueInternal(message, field, value);
- }
- void GeneratedMessageReflection::SetEnumValueInternal(
- Message* message, const FieldDescriptor* field,
- int value) const {
- if (field->is_extension()) {
- MutableExtensionSet(message)->SetEnum(field->number(), field->type(),
- value, field);
- } else {
- SetField<int>(message, field, value);
- }
- }
- const EnumValueDescriptor* GeneratedMessageReflection::GetRepeatedEnum(
- const Message& message, const FieldDescriptor* field, int index) const {
- // Usage checked by GetRepeatedEnumValue.
- int value = GetRepeatedEnumValue(message, field, index);
- return field->enum_type()->FindValueByNumberCreatingIfUnknown(value);
- }
- int GeneratedMessageReflection::GetRepeatedEnumValue(
- const Message& message, const FieldDescriptor* field, int index) const {
- USAGE_CHECK_ALL(GetRepeatedEnumValue, REPEATED, ENUM);
- int value;
- if (field->is_extension()) {
- value = GetExtensionSet(message).GetRepeatedEnum(field->number(), index);
- } else {
- value = GetRepeatedField<int>(message, field, index);
- }
- return value;
- }
- void GeneratedMessageReflection::SetRepeatedEnum(
- Message* message,
- const FieldDescriptor* field, int index,
- const EnumValueDescriptor* value) const {
- // Usage checked by SetRepeatedEnumValue.
- USAGE_CHECK_ENUM_VALUE(SetRepeatedEnum);
- SetRepeatedEnumValueInternal(message, field, index, value->number());
- }
- void GeneratedMessageReflection::SetRepeatedEnumValue(
- Message* message,
- const FieldDescriptor* field, int index,
- int value) const {
- USAGE_CHECK_ALL(SetRepeatedEnum, REPEATED, ENUM);
- if (!CreateUnknownEnumValues(descriptor_->file())) {
- // Check that the value is valid if we don't support direct storage of
- // unknown enum values.
- const EnumValueDescriptor* value_desc =
- field->enum_type()->FindValueByNumber(value);
- if (value_desc == NULL) {
- GOOGLE_LOG(DFATAL) << "SetRepeatedEnumValue accepts only valid integer values: "
- << "value " << value << " unexpected for field "
- << field->full_name();
- // In production builds, DFATAL will not terminate the program, so we have
- // to do something reasonable: just set the default value.
- value = field->default_value_enum()->number();
- }
- }
- SetRepeatedEnumValueInternal(message, field, index, value);
- }
- void GeneratedMessageReflection::SetRepeatedEnumValueInternal(
- Message* message,
- const FieldDescriptor* field, int index,
- int value) const {
- if (field->is_extension()) {
- MutableExtensionSet(message)->SetRepeatedEnum(
- field->number(), index, value);
- } else {
- SetRepeatedField<int>(message, field, index, value);
- }
- }
- void GeneratedMessageReflection::AddEnum(
- Message* message, const FieldDescriptor* field,
- const EnumValueDescriptor* value) const {
- // Usage checked by AddEnumValue.
- USAGE_CHECK_ENUM_VALUE(AddEnum);
- AddEnumValueInternal(message, field, value->number());
- }
- void GeneratedMessageReflection::AddEnumValue(
- Message* message, const FieldDescriptor* field,
- int value) const {
- USAGE_CHECK_ALL(AddEnum, REPEATED, ENUM);
- if (!CreateUnknownEnumValues(descriptor_->file())) {
- // Check that the value is valid if we don't support direct storage of
- // unknown enum values.
- const EnumValueDescriptor* value_desc =
- field->enum_type()->FindValueByNumber(value);
- if (value_desc == NULL) {
- GOOGLE_LOG(DFATAL) << "AddEnumValue accepts only valid integer values: value "
- << value << " unexpected for field " << field->full_name();
- // In production builds, DFATAL will not terminate the program, so we have
- // to do something reasonable: just set the default value.
- value = field->default_value_enum()->number();
- }
- }
- AddEnumValueInternal(message, field, value);
- }
- void GeneratedMessageReflection::AddEnumValueInternal(
- Message* message, const FieldDescriptor* field,
- int value) const {
- if (field->is_extension()) {
- MutableExtensionSet(message)->AddEnum(field->number(), field->type(),
- field->options().packed(),
- value, field);
- } else {
- AddField<int>(message, field, value);
- }
- }
- // -------------------------------------------------------------------
- const Message& GeneratedMessageReflection::GetMessage(
- const Message& message, const FieldDescriptor* field,
- MessageFactory* factory) const {
- USAGE_CHECK_ALL(GetMessage, SINGULAR, MESSAGE);
- if (factory == NULL) factory = message_factory_;
- if (field->is_extension()) {
- return static_cast<const Message&>(
- GetExtensionSet(message).GetMessage(
- field->number(), field->message_type(), 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 (factory == NULL) factory = message_factory_;
- if (field->is_extension()) {
- return static_cast<Message*>(
- MutableExtensionSet(message)->MutableMessage(field, factory));
- } else {
- Message* result;
- Message** result_holder = MutableRaw<Message*>(message, field);
- if (field->containing_oneof()) {
- if (!HasOneofField(*message, field)) {
- ClearOneof(message, field->containing_oneof());
- result_holder = MutableField<Message*>(message, field);
- const Message* default_message = DefaultRaw<const Message*>(field);
- *result_holder = default_message->New(message->GetArena());
- }
- } else {
- SetBit(message, field);
- }
- if (*result_holder == NULL) {
- const Message* default_message = DefaultRaw<const Message*>(field);
- *result_holder = default_message->New(message->GetArena());
- }
- result = *result_holder;
- return result;
- }
- }
- void GeneratedMessageReflection::UnsafeArenaSetAllocatedMessage(
- Message* message,
- Message* sub_message,
- const FieldDescriptor* field) const {
- USAGE_CHECK_ALL(SetAllocatedMessage, SINGULAR, MESSAGE);
- if (field->is_extension()) {
- MutableExtensionSet(message)->UnsafeArenaSetAllocatedMessage(
- field->number(), field->type(), field, sub_message);
- } else {
- if (field->containing_oneof()) {
- if (sub_message == NULL) {
- ClearOneof(message, field->containing_oneof());
- return;
- }
- ClearOneof(message, field->containing_oneof());
- *MutableRaw<Message*>(message, field) = sub_message;
- SetOneofCase(message, field);
- return;
- }
- if (sub_message == NULL) {
- ClearBit(message, field);
- } else {
- SetBit(message, field);
- }
- Message** sub_message_holder = MutableRaw<Message*>(message, field);
- if (GetArena(message) == NULL) {
- delete *sub_message_holder;
- }
- *sub_message_holder = sub_message;
- }
- }
- void GeneratedMessageReflection::SetAllocatedMessage(
- Message* message,
- Message* sub_message,
- const FieldDescriptor* field) const {
- // If message and sub-message are in different memory ownership domains
- // (different arenas, or one is on heap and one is not), then we may need to
- // do a copy.
- if (sub_message != NULL &&
- sub_message->GetArena() != message->GetArena()) {
- if (sub_message->GetArena() == NULL && message->GetArena() != NULL) {
- // Case 1: parent is on an arena and child is heap-allocated. We can add
- // the child to the arena's Own() list to free on arena destruction, then
- // set our pointer.
- message->GetArena()->Own(sub_message);
- UnsafeArenaSetAllocatedMessage(message, sub_message, field);
- } else {
- // Case 2: all other cases. We need to make a copy. MutableMessage() will
- // either get the existing message object, or instantiate a new one as
- // appropriate w.r.t. our arena.
- Message* sub_message_copy = MutableMessage(message, field);
- sub_message_copy->CopyFrom(*sub_message);
- }
- } else {
- // Same memory ownership domains.
- UnsafeArenaSetAllocatedMessage(message, sub_message, field);
- }
- }
- Message* GeneratedMessageReflection::UnsafeArenaReleaseMessage(
- Message* message,
- const FieldDescriptor* field,
- MessageFactory* factory) const {
- USAGE_CHECK_ALL(ReleaseMessage, SINGULAR, MESSAGE);
- if (factory == NULL) factory = message_factory_;
- if (field->is_extension()) {
- return static_cast<Message*>(
- MutableExtensionSet(message)->UnsafeArenaReleaseMessage(field,
- factory));
- } else {
- if (!(field->is_repeated() || field->containing_oneof())) {
- ClearBit(message, field);
- }
- if (field->containing_oneof()) {
- if (HasOneofField(*message, field)) {
- *MutableOneofCase(message, field->containing_oneof()) = 0;
- } else {
- return NULL;
- }
- }
- Message** result = MutableRaw<Message*>(message, field);
- Message* ret = *result;
- *result = NULL;
- return ret;
- }
- }
- Message* GeneratedMessageReflection::ReleaseMessage(
- Message* message,
- const FieldDescriptor* field,
- MessageFactory* factory) const {
- Message* released = UnsafeArenaReleaseMessage(message, field, factory);
- if (GetArena(message) != NULL && released != NULL) {
- Message* copy_from_arena = released->New();
- copy_from_arena->CopyFrom(*released);
- released = copy_from_arena;
- }
- return released;
- }
- 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 {
- if (IsMapFieldInApi(field)) {
- return GetRaw<MapFieldBase>(message, field)
- .GetRepeatedField()
- .Get<GenericTypeHandler<Message> >(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 {
- if (IsMapFieldInApi(field)) {
- return MutableRaw<MapFieldBase>(message, field)
- ->MutableRepeatedField()
- ->Mutable<GenericTypeHandler<Message> >(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 {
- Message* result = NULL;
- // We can't use AddField<Message>() because RepeatedPtrFieldBase doesn't
- // know how to allocate one.
- RepeatedPtrFieldBase* repeated = NULL;
- if (IsMapFieldInApi(field)) {
- repeated =
- MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
- } else {
- repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
- }
- 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(message->GetArena());
- // We can guarantee here that repeated and result are either both heap
- // allocated or arena owned. So it is safe to call the unsafe version
- // of AddAllocated.
- repeated->UnsafeArenaAddAllocated<GenericTypeHandler<Message> >(result);
- }
- return result;
- }
- }
- void GeneratedMessageReflection::AddAllocatedMessage(
- Message* message, const FieldDescriptor* field,
- Message* new_entry) const {
- USAGE_CHECK_ALL(AddAllocatedMessage, REPEATED, MESSAGE);
- if (field->is_extension()) {
- MutableExtensionSet(message)->AddAllocatedMessage(field, new_entry);
- } else {
- RepeatedPtrFieldBase* repeated = NULL;
- if (IsMapFieldInApi(field)) {
- repeated =
- MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
- } else {
- repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
- }
- repeated->AddAllocated<GenericTypeHandler<Message> >(new_entry);
- }
- }
- void* GeneratedMessageReflection::MutableRawRepeatedField(
- Message* message, const FieldDescriptor* field,
- FieldDescriptor::CppType cpptype,
- int ctype, const Descriptor* desc) const {
- USAGE_CHECK_REPEATED("MutableRawRepeatedField");
- if (field->cpp_type() != cpptype)
- ReportReflectionUsageTypeError(descriptor_,
- field, "MutableRawRepeatedField", cpptype);
- if (ctype >= 0)
- GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
- if (desc != NULL)
- GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
- if (field->is_extension()) {
- return MutableExtensionSet(message)->MutableRawRepeatedField(
- field->number(), field->type(), field->is_packed(), field);
- } else {
- // Trigger transform for MapField
- if (IsMapFieldInApi(field)) {
- return MutableRawNonOneof<MapFieldBase>(message, field)
- ->MutableRepeatedField();
- }
- return MutableRawNonOneof<void>(message, field);
- }
- }
- const void* GeneratedMessageReflection::GetRawRepeatedField(
- const Message& message, const FieldDescriptor* field,
- FieldDescriptor::CppType cpptype,
- int ctype, const Descriptor* desc) const {
- USAGE_CHECK_REPEATED("GetRawRepeatedField");
- if (field->cpp_type() != cpptype)
- ReportReflectionUsageTypeError(descriptor_,
- field, "GetRawRepeatedField", cpptype);
- if (ctype >= 0)
- GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
- if (desc != NULL)
- GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
- if (field->is_extension()) {
- // Should use extension_set::GetRawRepeatedField. However, the required
- // parameter "default repeated value" is not very easy to get here.
- // Map is not supported in extensions, it is acceptable to use
- // extension_set::MutableRawRepeatedField which does not change the message.
- return MutableExtensionSet(const_cast<Message*>(&message))
- ->MutableRawRepeatedField(
- field->number(), field->type(), field->is_packed(), field);
- } else {
- // Trigger transform for MapField
- if (IsMapFieldInApi(field)) {
- return &(GetRawNonOneof<MapFieldBase>(message, field).GetRepeatedField());
- }
- return &GetRawNonOneof<char>(message, field);
- }
- }
- const FieldDescriptor* GeneratedMessageReflection::GetOneofFieldDescriptor(
- const Message& message,
- const OneofDescriptor* oneof_descriptor) const {
- uint32 field_number = GetOneofCase(message, oneof_descriptor);
- if (field_number == 0) {
- return NULL;
- }
- return descriptor_->FindFieldByNumber(field_number);
- }
- bool GeneratedMessageReflection::ContainsMapKey(
- const Message& message,
- const FieldDescriptor* field,
- const MapKey& key) const {
- USAGE_CHECK(IsMapFieldInApi(field),
- "LookupMapValue",
- "Field is not a map field.");
- return GetRaw<MapFieldBase>(message, field).ContainsMapKey(key);
- }
- bool GeneratedMessageReflection::InsertOrLookupMapValue(
- Message* message,
- const FieldDescriptor* field,
- const MapKey& key,
- MapValueRef* val) const {
- USAGE_CHECK(IsMapFieldInApi(field),
- "InsertOrLookupMapValue",
- "Field is not a map field.");
- val->SetType(field->message_type()->FindFieldByName("value")->cpp_type());
- return MutableRaw<MapFieldBase>(message, field)->InsertOrLookupMapValue(
- key, val);
- }
- bool GeneratedMessageReflection::DeleteMapValue(
- Message* message,
- const FieldDescriptor* field,
- const MapKey& key) const {
- USAGE_CHECK(IsMapFieldInApi(field),
- "DeleteMapValue",
- "Field is not a map field.");
- return MutableRaw<MapFieldBase>(message, field)->DeleteMapValue(key);
- }
- MapIterator GeneratedMessageReflection::MapBegin(
- Message* message,
- const FieldDescriptor* field) const {
- USAGE_CHECK(IsMapFieldInApi(field),
- "MapBegin",
- "Field is not a map field.");
- MapIterator iter(message, field);
- GetRaw<MapFieldBase>(*message, field).MapBegin(&iter);
- return iter;
- }
- MapIterator GeneratedMessageReflection::MapEnd(
- Message* message,
- const FieldDescriptor* field) const {
- USAGE_CHECK(IsMapFieldInApi(field),
- "MapEnd",
- "Field is not a map field.");
- MapIterator iter(message, field);
- GetRaw<MapFieldBase>(*message, field).MapEnd(&iter);
- return iter;
- }
- int GeneratedMessageReflection::MapSize(
- const Message& message,
- const FieldDescriptor* field) const {
- USAGE_CHECK(IsMapFieldInApi(field),
- "MapSize",
- "Field is not a map field.");
- return GetRaw<MapFieldBase>(message, field).size();
- }
- // -----------------------------------------------------------------------------
- const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
- const string& name) const {
- if (!schema_.HasExtensionSet()) 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.
- const int type_extension_count = type->extension_count();
- 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 (!schema_.HasExtensionSet()) return NULL;
- return descriptor_pool_->FindExtensionByNumber(descriptor_, number);
- }
- bool GeneratedMessageReflection::SupportsUnknownEnumValues() const {
- return CreateUnknownEnumValues(descriptor_->file());
- }
- // ===================================================================
- // Some private helpers.
- // These simple template accessors obtain pointers (or references) to
- // the given field.
- template <class Type>
- const Type& GeneratedMessageReflection::GetRawNonOneof(
- const Message& message, const FieldDescriptor* field) const {
- return GetConstRefAtOffset<Type>(message,
- schema_.GetFieldOffsetNonOneof(field));
- }
- template <class Type>
- Type* GeneratedMessageReflection::MutableRawNonOneof(
- Message* message, const FieldDescriptor* field) const {
- return GetPointerAtOffset<Type>(message,
- schema_.GetFieldOffsetNonOneof(field));
- }
- template <typename Type>
- const Type& GeneratedMessageReflection::GetRaw(
- const Message& message, const FieldDescriptor* field) const {
- if (field->containing_oneof() && !HasOneofField(message, field)) {
- return DefaultRaw<Type>(field);
- }
- return GetConstRefAtOffset<Type>(message, schema_.GetFieldOffset(field));
- }
- bool GeneratedMessageReflection::IsInlined(const FieldDescriptor* field) const {
- return schema_.IsFieldInlined(field);
- }
- template <typename Type>
- Type* GeneratedMessageReflection::MutableRaw(Message* message,
- const FieldDescriptor* field) const {
- return GetPointerAtOffset<Type>(message, schema_.GetFieldOffset(field));
- }
- inline const uint32* GeneratedMessageReflection::GetHasBits(
- const Message& message) const {
- GOOGLE_DCHECK(schema_.HasHasbits());
- return &GetConstRefAtOffset<uint32>(message, schema_.HasBitsOffset());
- }
- inline uint32* GeneratedMessageReflection::MutableHasBits(
- Message* message) const {
- GOOGLE_DCHECK(schema_.HasHasbits());
- return GetPointerAtOffset<uint32>(message, schema_.HasBitsOffset());
- }
- inline uint32 GeneratedMessageReflection::GetOneofCase(
- const Message& message, const OneofDescriptor* oneof_descriptor) const {
- return GetConstRefAtOffset<uint32>(
- message, schema_.GetOneofCaseOffset(oneof_descriptor));
- }
- inline uint32* GeneratedMessageReflection::MutableOneofCase(
- Message* message, const OneofDescriptor* oneof_descriptor) const {
- return GetPointerAtOffset<uint32>(
- message, schema_.GetOneofCaseOffset(oneof_descriptor));
- }
- inline const ExtensionSet& GeneratedMessageReflection::GetExtensionSet(
- const Message& message) const {
- return GetConstRefAtOffset<ExtensionSet>(message,
- schema_.GetExtensionSetOffset());
- }
- inline ExtensionSet* GeneratedMessageReflection::MutableExtensionSet(
- Message* message) const {
- return GetPointerAtOffset<ExtensionSet>(message,
- schema_.GetExtensionSetOffset());
- }
- inline Arena* GeneratedMessageReflection::GetArena(Message* message) const {
- return GetInternalMetadataWithArena(*message).arena();
- }
- inline const InternalMetadataWithArena&
- GeneratedMessageReflection::GetInternalMetadataWithArena(
- const Message& message) const {
- return GetConstRefAtOffset<InternalMetadataWithArena>(
- message, schema_.GetMetadataOffset());
- }
- inline InternalMetadataWithArena*
- GeneratedMessageReflection::MutableInternalMetadataWithArena(
- Message* message) const {
- return GetPointerAtOffset<InternalMetadataWithArena>(
- message, schema_.GetMetadataOffset());
- }
- template <typename Type>
- inline const Type& GeneratedMessageReflection::DefaultRaw(
- const FieldDescriptor* field) const {
- return *reinterpret_cast<const Type*>(schema_.GetFieldDefault(field));
- }
- // Simple accessors for manipulating has_bits_.
- inline bool GeneratedMessageReflection::HasBit(
- const Message& message, const FieldDescriptor* field) const {
- GOOGLE_DCHECK(!field->options().weak());
- if (schema_.HasHasbits()) {
- return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field));
- }
- // proto3: no has-bits. All fields present except messages, which are
- // present only if their message-field pointer is non-NULL.
- if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
- return !schema_.IsDefaultInstance(message) &&
- GetRaw<const Message*>(message, field) != NULL;
- } else {
- // Non-message field (and non-oneof, since that was handled in HasField()
- // before calling us), and singular (again, checked in HasField). So, this
- // field must be a scalar.
- // Scalar primitive (numeric or string/bytes) fields are present if
- // their value is non-zero (numeric) or non-empty (string/bytes). N.B.:
- // we must use this definition here, rather than the "scalar fields
- // always present" in the proto3 docs, because MergeFrom() semantics
- // require presence as "present on wire", and reflection-based merge
- // (which uses HasField()) needs to be consistent with this.
- switch (field->cpp_type()) {
- case FieldDescriptor::CPPTYPE_STRING:
- switch (field->options().ctype()) {
- default: {
- if (IsInlined(field)) {
- return !GetField<InlinedStringField>(message, field)
- .GetNoArena().empty();
- }
- return GetField<ArenaStringPtr>(message, field).Get().size() > 0;
- }
- }
- return false;
- case FieldDescriptor::CPPTYPE_BOOL:
- return GetRaw<bool>(message, field) != false;
- case FieldDescriptor::CPPTYPE_INT32:
- return GetRaw<int32>(message, field) != 0;
- case FieldDescriptor::CPPTYPE_INT64:
- return GetRaw<int64>(message, field) != 0;
- case FieldDescriptor::CPPTYPE_UINT32:
- return GetRaw<uint32>(message, field) != 0;
- case FieldDescriptor::CPPTYPE_UINT64:
- return GetRaw<uint64>(message, field) != 0;
- case FieldDescriptor::CPPTYPE_FLOAT:
- return GetRaw<float>(message, field) != 0.0;
- case FieldDescriptor::CPPTYPE_DOUBLE:
- return GetRaw<double>(message, field) != 0.0;
- case FieldDescriptor::CPPTYPE_ENUM:
- return GetRaw<int>(message, field) != 0;
- case FieldDescriptor::CPPTYPE_MESSAGE:
- // handled above; avoid warning
- break;
- }
- GOOGLE_LOG(FATAL) << "Reached impossible case in HasBit().";
- return false;
- }
- }
- inline void GeneratedMessageReflection::SetBit(
- Message* message, const FieldDescriptor* field) const {
- GOOGLE_DCHECK(!field->options().weak());
- if (!schema_.HasHasbits()) {
- return;
- }
- const uint32 index = schema_.HasBitIndex(field);
- MutableHasBits(message)[index / 32] |=
- (static_cast<uint32>(1) << (index % 32));
- }
- inline void GeneratedMessageReflection::ClearBit(
- Message* message, const FieldDescriptor* field) const {
- GOOGLE_DCHECK(!field->options().weak());
- if (!schema_.HasHasbits()) {
- return;
- }
- const uint32 index = schema_.HasBitIndex(field);
- MutableHasBits(message)[index / 32] &=
- ~(static_cast<uint32>(1) << (index % 32));
- }
- inline void GeneratedMessageReflection::SwapBit(
- Message* message1, Message* message2, const FieldDescriptor* field) const {
- GOOGLE_DCHECK(!field->options().weak());
- if (!schema_.HasHasbits()) {
- return;
- }
- bool temp_has_bit = HasBit(*message1, field);
- if (HasBit(*message2, field)) {
- SetBit(message1, field);
- } else {
- ClearBit(message1, field);
- }
- if (temp_has_bit) {
- SetBit(message2, field);
- } else {
- ClearBit(message2, field);
- }
- }
- inline bool GeneratedMessageReflection::HasOneof(
- const Message& message, const OneofDescriptor* oneof_descriptor) const {
- return (GetOneofCase(message, oneof_descriptor) > 0);
- }
- inline bool GeneratedMessageReflection::HasOneofField(
- const Message& message, const FieldDescriptor* field) const {
- return (GetOneofCase(message, field->containing_oneof()) == field->number());
- }
- inline void GeneratedMessageReflection::SetOneofCase(
- Message* message, const FieldDescriptor* field) const {
- *MutableOneofCase(message, field->containing_oneof()) = field->number();
- }
- inline void GeneratedMessageReflection::ClearOneofField(
- Message* message, const FieldDescriptor* field) const {
- if (HasOneofField(*message, field)) {
- ClearOneof(message, field->containing_oneof());
- }
- }
- inline void GeneratedMessageReflection::ClearOneof(
- Message* message, const OneofDescriptor* oneof_descriptor) const {
- // TODO(jieluo): Consider to cache the unused object instead of deleting
- // it. It will be much faster if an application switches a lot from
- // a few oneof fields. Time/space tradeoff
- uint32 oneof_case = GetOneofCase(*message, oneof_descriptor);
- if (oneof_case > 0) {
- const FieldDescriptor* field = descriptor_->FindFieldByNumber(oneof_case);
- if (GetArena(message) == NULL) {
- switch (field->cpp_type()) {
- case FieldDescriptor::CPPTYPE_STRING: {
- switch (field->options().ctype()) {
- default: // TODO(kenton): Support other string reps.
- case FieldOptions::STRING: {
- const string* default_ptr =
- &DefaultRaw<ArenaStringPtr>(field).Get();
- MutableField<ArenaStringPtr>(message, field)->
- Destroy(default_ptr, GetArena(message));
- break;
- }
- }
- break;
- }
- case FieldDescriptor::CPPTYPE_MESSAGE:
- delete *MutableRaw<Message*>(message, field);
- break;
- default:
- break;
- }
- }
- *MutableOneofCase(message, oneof_descriptor) = 0;
- }
- }
- // 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 {
- if (field->containing_oneof() && !HasOneofField(*message, field)) {
- ClearOneof(message, field->containing_oneof());
- }
- *MutableRaw<Type>(message, field) = value;
- field->containing_oneof() ?
- SetOneofCase(message, field) : SetBit(message, field);
- }
- template <typename Type>
- inline Type* GeneratedMessageReflection::MutableField(
- Message* message, const FieldDescriptor* field) const {
- field->containing_oneof() ?
- SetOneofCase(message, field) : 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();
- }
- MessageFactory* GeneratedMessageReflection::GetMessageFactory() const {
- return message_factory_;
- }
- void* GeneratedMessageReflection::RepeatedFieldData(
- Message* message, const FieldDescriptor* field,
- FieldDescriptor::CppType cpp_type,
- const Descriptor* message_type) const {
- GOOGLE_CHECK(field->is_repeated());
- GOOGLE_CHECK(field->cpp_type() == cpp_type ||
- (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
- cpp_type == FieldDescriptor::CPPTYPE_INT32))
- << "The type parameter T in RepeatedFieldRef<T> API doesn't match "
- << "the actual field type (for enums T should be the generated enum "
- << "type or int32).";
- if (message_type != NULL) {
- GOOGLE_CHECK_EQ(message_type, field->message_type());
- }
- if (field->is_extension()) {
- return MutableExtensionSet(message)->MutableRawRepeatedField(
- field->number(), field->type(), field->is_packed(), field);
- } else {
- return MutableRawNonOneof<char>(message, field);
- }
- }
- MapFieldBase* GeneratedMessageReflection::MapData(
- Message* message, const FieldDescriptor* field) const {
- USAGE_CHECK(IsMapFieldInApi(field),
- "GetMapData",
- "Field is not a map field.");
- return MutableRaw<MapFieldBase>(message, field);
- }
- namespace {
- // Helper function to transform migration schema into reflection schema.
- ReflectionSchema MigrationToReflectionSchema(
- const Message* const* default_instance, const uint32* offsets,
- MigrationSchema migration_schema) {
- ReflectionSchema result;
- result.default_instance_ = *default_instance;
- // First 6 offsets are offsets to the special fields. The following offsets
- // are the proto fields.
- result.offsets_ = offsets + migration_schema.offsets_index + 5;
- result.has_bit_indices_ = offsets + migration_schema.has_bit_indices_index;
- result.has_bits_offset_ = offsets[migration_schema.offsets_index + 0];
- result.metadata_offset_ = offsets[migration_schema.offsets_index + 1];
- result.extensions_offset_ = offsets[migration_schema.offsets_index + 2];
- result.oneof_case_offset_ = offsets[migration_schema.offsets_index + 3];
- result.object_size_ = migration_schema.object_size;
- result.weak_field_map_offset_ = offsets[migration_schema.offsets_index + 4];
- return result;
- }
- template<typename Schema>
- class AssignDescriptorsHelper {
- public:
- AssignDescriptorsHelper(MessageFactory* factory,
- Metadata* file_level_metadata,
- const EnumDescriptor** file_level_enum_descriptors,
- const Schema* schemas,
- const Message* const* default_instance_data,
- const uint32* offsets)
- : factory_(factory),
- file_level_metadata_(file_level_metadata),
- file_level_enum_descriptors_(file_level_enum_descriptors),
- schemas_(schemas),
- default_instance_data_(default_instance_data),
- offsets_(offsets) {}
- void AssignMessageDescriptor(const Descriptor* descriptor) {
- for (int i = 0; i < descriptor->nested_type_count(); i++) {
- AssignMessageDescriptor(descriptor->nested_type(i));
- }
- file_level_metadata_->descriptor = descriptor;
- file_level_metadata_->reflection = new GeneratedMessageReflection(
- descriptor,
- MigrationToReflectionSchema(default_instance_data_, offsets_,
- *schemas_),
- ::google::protobuf::DescriptorPool::generated_pool(), factory_);
- for (int i = 0; i < descriptor->enum_type_count(); i++) {
- AssignEnumDescriptor(descriptor->enum_type(i));
- }
- schemas_++;
- default_instance_data_++;
- file_level_metadata_++;
- }
- void AssignEnumDescriptor(const EnumDescriptor* descriptor) {
- *file_level_enum_descriptors_ = descriptor;
- file_level_enum_descriptors_++;
- }
- const Metadata* GetCurrentMetadataPtr() const { return file_level_metadata_; }
- private:
- MessageFactory* factory_;
- Metadata* file_level_metadata_;
- const EnumDescriptor** file_level_enum_descriptors_;
- const Schema* schemas_;
- const Message* const * default_instance_data_;
- const uint32* offsets_;
- };
- // We have the routines that assign descriptors and build reflection
- // automatically delete the allocated reflection. MetadataOwner owns
- // all the allocated reflection instances.
- struct MetadataOwner {
- ~MetadataOwner() {
- for (auto range : metadata_arrays_) {
- for (const Metadata* m = range.first; m < range.second; m++) {
- delete m->reflection;
- }
- }
- }
- void AddArray(const Metadata* begin, const Metadata* end) {
- MutexLock lock(&mu_);
- metadata_arrays_.push_back(std::make_pair(begin, end));
- }
- static MetadataOwner* Instance() {
- static MetadataOwner* res = OnShutdownDelete(new MetadataOwner);
- return res;
- }
- private:
- MetadataOwner() = default; // private because singleton
- Mutex mu_;
- std::vector<std::pair<const Metadata*, const Metadata*> > metadata_arrays_;
- };
- } // namespace
- void AssignDescriptors(
- const string& filename, const MigrationSchema* schemas,
- const Message* const* default_instances_, const uint32* offsets,
- // update the following descriptor arrays.
- Metadata* file_level_metadata,
- const EnumDescriptor** file_level_enum_descriptors,
- const ServiceDescriptor** file_level_service_descriptors) {
- const ::google::protobuf::FileDescriptor* file =
- ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(filename);
- GOOGLE_CHECK(file != NULL);
- MessageFactory* factory = MessageFactory::generated_factory();
- AssignDescriptorsHelper<MigrationSchema> helper(factory, file_level_metadata,
- file_level_enum_descriptors, schemas,
- default_instances_, offsets);
- for (int i = 0; i < file->message_type_count(); i++) {
- helper.AssignMessageDescriptor(file->message_type(i));
- }
- for (int i = 0; i < file->enum_type_count(); i++) {
- helper.AssignEnumDescriptor(file->enum_type(i));
- }
- if (file->options().cc_generic_services()) {
- for (int i = 0; i < file->service_count(); i++) {
- file_level_service_descriptors[i] = file->service(i);
- }
- }
- MetadataOwner::Instance()->AddArray(
- file_level_metadata, helper.GetCurrentMetadataPtr());
- }
- void RegisterAllTypesInternal(const Metadata* file_level_metadata, int size) {
- for (int i = 0; i < size; i++) {
- const GeneratedMessageReflection* reflection =
- static_cast<const GeneratedMessageReflection*>(
- file_level_metadata[i].reflection);
- if (reflection) {
- // It's not a map type
- ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
- file_level_metadata[i].descriptor,
- reflection->schema_.default_instance_);
- }
- }
- }
- void RegisterAllTypes(const Metadata* file_level_metadata, int size) {
- RegisterAllTypesInternal(file_level_metadata, size);
- }
- void UnknownFieldSetSerializer(const uint8* base, uint32 offset, uint32 tag,
- uint32 has_offset,
- ::google::protobuf::io::CodedOutputStream* output) {
- const void* ptr = base + offset;
- const InternalMetadataWithArena* metadata =
- static_cast<const InternalMetadataWithArena*>(ptr);
- if (metadata->have_unknown_fields()) {
- ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
- metadata->unknown_fields(), output);
- }
- }
- } // namespace internal
- } // namespace protobuf
- } // namespace google
|