title: Protocol Buffers - how is the extensibility and backward compatibility achieved?
body: <p>Please help me understand the backward compatibility and extensibility properties of the protocol buffers' internal implementation. </p>
  
  <ol>
  <li><p>How is backwards compatibility achieved in the face of deleting data fields? I imagine that the generated data access code returns empty values for properties that are not present in the data stream, and the consumer code has to always specifically check for those empty values and act accordingly. How would the empty values be standardized? </p>
  
  <p>Also in this case, how does the old code "know" that the property is not present in the data stream anymore? </p>
  
  <p>I imagine that one solution would be that old data is never deleted from the internal stream specification and only replaced with empty values but the same could be probably achieved with internal versioning on the fields.</p></li>
  <li><p>Perhaps a more clear question: how does the old code know to ignore new data added by new versions of the .proto spec? This is probably somewhat more straightforward than 1) by having a size field in the internal serialized structure, and only reading that many bytes at a time, while also only appending new fields at the end of the struct.</p></li>
  </ol>
  
  <p>Trying to understand all this in order to extend an old data format to provide backward/forward compatibility between code and data as a side project.</p>
  
  <p>Edit: formatting.</p>
  
  <p>Thanks!</p>