code: func (m *Message) FromProto(p proto.Message) error {
  	ptr := reflect.ValueOf(p)
  	if ptr.Type() != m.typ.Type() {
  		return fmt.Errorf("bad message type: got %s, expect %s", ptr.Type(), m.typ.Type())
  	}
  
  	msg := ptr.Elem()
  	for name, fd := range m.typ.fields {
  		// Get the field's value from the proto message as reflect.Value. For unused
  		// oneof alternatives this is an invalid zero value, we skip them right
  		// away. For other fields it is reflect.Value (of fd.typ type) that MAY be
  		// nil inside (for unset fields). toStarlarkValue converts such values to
  		// starlark.None.
  		val := fd.onProtoReflection(msg, reflectFromProto)
  		if !val.IsValid() {
  			continue
  		}
  		// Convert the Go value to the corresponding Starlark value and assign it to
  		// the field in 'm'.
  		sv, err := toStarlarkValue(val)
  		if err != nil {
  			return fmt.Errorf("cannot recognize value of field %s: %s", name, err)
  		}
  		if err := m.SetField(name, sv); err != nil {
  			return err
  		}
  	}
  
  	return nil
  }
docs: // FromProto populates fields of this message based on values in proto.Message.
  //
  // Returns an error on type mismatch.