| 3824 | } |
| 3825 | |
| 3826 | bool DescriptorBuilder::OptionInterpreter::InterpretOptions( |
| 3827 | OptionsToInterpret* options_to_interpret) { |
| 3828 | // Note that these may be in different pools, so we can't use the same |
| 3829 | // descriptor and reflection objects on both. |
| 3830 | Message* options = options_to_interpret->options; |
| 3831 | const Message* original_options = options_to_interpret->original_options; |
| 3832 | |
| 3833 | bool failed = false; |
| 3834 | options_to_interpret_ = options_to_interpret; |
| 3835 | |
| 3836 | // Find the uninterpreted_option field in the mutable copy of the options |
| 3837 | // and clear them, since we're about to interpret them. |
| 3838 | const FieldDescriptor* uninterpreted_options_field = |
| 3839 | options->GetDescriptor()->FindFieldByName("uninterpreted_option"); |
| 3840 | GOOGLE_CHECK(uninterpreted_options_field != NULL) |
| 3841 | << "No field named \"uninterpreted_option\" in the Options proto."; |
| 3842 | options->GetReflection()->ClearField(options, uninterpreted_options_field); |
| 3843 | |
| 3844 | // Find the uninterpreted_option field in the original options. |
| 3845 | const FieldDescriptor* original_uninterpreted_options_field = |
| 3846 | original_options->GetDescriptor()-> |
| 3847 | FindFieldByName("uninterpreted_option"); |
| 3848 | GOOGLE_CHECK(original_uninterpreted_options_field != NULL) |
| 3849 | << "No field named \"uninterpreted_option\" in the Options proto."; |
| 3850 | |
| 3851 | const int num_uninterpreted_options = original_options->GetReflection()-> |
| 3852 | FieldSize(*original_options, original_uninterpreted_options_field); |
| 3853 | for (int i = 0; i < num_uninterpreted_options; ++i) { |
| 3854 | uninterpreted_option_ = down_cast<const UninterpretedOption*>( |
| 3855 | &original_options->GetReflection()->GetRepeatedMessage( |
| 3856 | *original_options, original_uninterpreted_options_field, i)); |
| 3857 | if (!InterpretSingleOption(options)) { |
| 3858 | // Error already added by InterpretSingleOption(). |
| 3859 | failed = true; |
| 3860 | break; |
| 3861 | } |
| 3862 | } |
| 3863 | // Reset these, so we don't have any dangling pointers. |
| 3864 | uninterpreted_option_ = NULL; |
| 3865 | options_to_interpret_ = NULL; |
| 3866 | |
| 3867 | if (!failed) { |
| 3868 | // InterpretSingleOption() added the interpreted options in the |
| 3869 | // UnknownFieldSet, in case the option isn't yet known to us. Now we |
| 3870 | // serialize the options message and deserialize it back. That way, any |
| 3871 | // option fields that we do happen to know about will get moved from the |
| 3872 | // UnknownFieldSet into the real fields, and thus be available right away. |
| 3873 | // If they are not known, that's OK too. They will get reparsed into the |
| 3874 | // UnknownFieldSet and wait there until the message is parsed by something |
| 3875 | // that does know about the options. |
| 3876 | string buf; |
| 3877 | options->AppendToString(&buf); |
| 3878 | GOOGLE_CHECK(options->ParseFromString(buf)) |
| 3879 | << "Protocol message serialized itself in invalid fashion."; |
| 3880 | } |
| 3881 | |
| 3882 | return !failed; |
| 3883 | } |
no test coverage detected